from typing import Tuple, Union

from fastapi import Request, Response

from common.pkg.jwt_util import decode_jwt_token
from common.route.route import CustomerBaseRoute
from common.utils.resp import JsonResponse, RC


# 必须是登陆用户
class MustLoginUserAPIRoute(CustomerBaseRoute):
    secret = ""

    async def do_before(self, request: Request, *args, **kwargs) -> Tuple[bool, Union[Response, None]]:
        if "Authorization" not in request.headers:
            return False, JsonResponse(code=RC.AUTH_FAILED, msg="缺失认证参数").to_response()
        auth = request.headers.get("Authorization")
        if not auth.startswith("Bearer "):
            return False, JsonResponse(code=RC.AUTH_FAILED, msg="token格式错误").to_response()
        _, token = auth.split()
        s = getattr(request.app.settings.jwt_config, self.secret)
        ok, payload = decode_jwt_token(token, s,
                                       request.app.settings.jwt_config.algorithms)
        if not ok:
            return False, JsonResponse(code=RC.AUTH_FAILED, msg="认证失败").to_response()
        request.state.user_id = payload.get("user_id")
        return True, None


# 可以是登陆用户， 也可以是非登陆用户
class AnyUserAPIRoute(CustomerBaseRoute):
    secret = ""
    async def do_before(self, request: Request, *args, **kwargs) -> Tuple[bool, Union[Response, None]]:
        if "Authorization" in request.headers:
            auth = request.headers.get("Authorization")
            if not auth.startswith("Bearer "):
                return False, JsonResponse(code=RC.AUTH_FAILED, msg="token格式错误").to_response()
            _, token = auth.split()
            s = getattr(request.app.settings.jwt_config, self.secret)
            ok, payload = decode_jwt_token(token, s,
                                           request.app.settings.jwt_config.algorithms)
            if not ok:
                return False, JsonResponse(code=RC.AUTH_FAILED, msg="认证失败").to_response()
            request.state.user_id = payload.get("user_id")
            request.state.login = True
            return True, None
        else:
            request.state.login = False
            return True, None


class TenantMustLoginAPIRoute(MustLoginUserAPIRoute):
    secret = "tenant_secret"


class TenantAnyUserAPIRoute(AnyUserAPIRoute):
    secret = "tenant_secret"


class ClientMustLoginAPIRoute(MustLoginUserAPIRoute):
    secret = "client_secret"


class ClientAnyUserAPIRoute(AnyUserAPIRoute):
    secret = "client_secret"






